package com.ztstech.matisse_android_plugin;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.net.Uri;
import android.os.Environment;
import android.text.TextUtils;

import androidx.annotation.NonNull;

import com.zhihu.matisse.Matisse;
import com.zhihu.matisse.MimeType;
import com.zhihu.matisse.internal.utils.PathUtils;
import com.ztstech.matisse_android_plugin.clip.TailorImageActivity;
import com.ztstech.matisse_android_plugin.matisse.MatissePhotoHelper;
import com.ztstech.matisse_android_plugin.matisse.MetisseConstant;

import java.io.File;
import java.util.List;

import io.flutter.Log;
import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.Registrar;

import static android.app.Activity.RESULT_OK;
import static com.ztstech.matisse_android_plugin.matisse.MetisseConstant.SCREEN_LANDSCAPE;
import static com.ztstech.matisse_android_plugin.matisse.MetisseConstant.SCREEN_PORTRAIT;
import static com.ztstech.matisse_android_plugin.matisse.MetisseConstant.SCREEN_SENSOR;

/**
 * MatisseAndroidPlugin
 */
public class MatisseAndroidPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware, PluginRegistry.ActivityResultListener {

    public static final String METHOD_CHANNEL = "plugins.flutter.ztstech.com/matisse_plugin";

    public static final String PLUGIN_KEY = "com.ztstech.matisse_android_plugin.MatisseAndroidPlugin";

    private MethodChannel.Result mResult;

    private Activity activity;

    private MethodChannel channel;

    private ActivityPluginBinding activityBinding;

    private int clipScaleX;

    private int clipScaleY;

    @Override
    public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
        channel = new MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), METHOD_CHANNEL);
        channel.setMethodCallHandler(this::onMethodCall);
    }

    // This static function is optional and equivalent to onAttachedToEngine. It supports the old
    // pre-Flutter-1.12 Android projects. You are encouraged to continue supporting
    // plugin registration via this function while apps migrate to use the new Android APIs
    // post-flutter-1.12 via https://flutter.dev/go/android-project-migration.
    //
    // It is encouraged to share logic between onAttachedToEngine and registerWith to keep
    // them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called
    // depending on the user's project. onAttachedToEngine or registerWith must both be defined
    // in the same class.
    public static void registerWith(PluginRegistry.Registrar registrar) {
//        Registrar registrar = registry.registrarFor(PLUGIN_KEY);
        MatisseAndroidPlugin plugin = new MatisseAndroidPlugin();
        plugin.registrarActivityResult(registrar);

    }

    /**
     * 添加OnActivityResult监听
     */
    private void registrarActivityResult(Registrar registrar) {
        channel = new MethodChannel(registrar.messenger(), METHOD_CHANNEL);
        activity = registrar.activity();
        channel.setMethodCallHandler(this::onMethodCall);
        registrar.addActivityResultListener(this::onActivityResult);
    }

    @Override
    public void onMethodCall(@NonNull MethodCall methodCall, @NonNull Result result) {
        if (methodCall == null || result == null) {
            return;
        }
        try {
            mResult = result;
            //最大图片数
            int maxImageSize = formatMaxChooseCount(methodCall.argument("maxImageSize") != null ? methodCall.argument("maxImageSize") : 0);
            //最大视频数
            int maxVideoSize = formatMaxChooseCount(methodCall.argument("maxVideoSize") != null ? methodCall.argument("maxVideoSize") : 0);
            //最大总数（适用于仅一种类型）
            int maxSize = formatMaxChooseCount(methodCall.argument("maxSize") != null ? methodCall.argument("maxSize") : 0);
            //是否支持混选
            boolean isCanMixSelect = methodCall.argument("isCanMixSelect") != null ? methodCall.argument("isCanMixSelect") : MetisseConstant.DEFAULT_MIX_SELECT;
            //支持方向
            int screenOrientation = formatScreenOrientation(methodCall.argument("screenOrientation") != null ? methodCall.argument("screenOrientation") : SCREEN_PORTRAIT);
            //网格总数
            int spanCount = methodCall.argument("spanCount") != null ? methodCall.argument("spanCount") : MetisseConstant.DEFAULT_SPAN_COUNT;
            //裁剪宽比
            clipScaleX = methodCall.argument("scaleX") != null ? methodCall.argument("scaleX") : MetisseConstant.DEFAULT_CLIP_SCALE_X;
            //裁剪高比
            clipScaleY = methodCall.argument("scaleY") != null ? methodCall.argument("scaleY") : MetisseConstant.DEFAULT_CLIP_SCALE_Y;

            //测试
            switch (methodCall.method) {
                //选择图片视频
                case "selectAll":
                    MatissePhotoHelper.selectAll(activity, maxImageSize, maxVideoSize, isCanMixSelect, screenOrientation, spanCount);
                    break;
                case "selectPhoto":
                    MatissePhotoHelper.selectPhoto(activity, maxSize, MimeType.ofImage(), screenOrientation, spanCount);
                    break;
                case "selectVideo":
                    MatissePhotoHelper.selectVideo(activity, maxSize, MimeType.ofVideo(), screenOrientation, spanCount);
                    break;
                case "selectFromAlbum":
                    MatissePhotoHelper.selectfromalbum(activity, maxSize, screenOrientation, spanCount);
                    break;
                case "clipOneImage":
                    MatissePhotoHelper.clipOnePhoto(activity, MimeType.ofImage(), screenOrientation, spanCount);
                    break;
                default:
                    result.notImplemented();
            }

        } catch (Exception e) {
            Log.d("zxx", "媒体选择异常:" + e.toString());
            e.printStackTrace();
            result.notImplemented();
        }
    }

    /**
     * 检查最大选择数
     * 至少选一个
     *
     * @return
     */
    private int formatMaxChooseCount(int max) {
        if (max < 1) {
            return 1;
        }
        return max;
    }

    /**
     * 转化屏幕参数
     *
     * @return
     */
    private int formatScreenOrientation(String screenType) {
        if (TextUtils.isEmpty(screenType)) {
            return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
        }
        if (TextUtils.equals(screenType, SCREEN_LANDSCAPE)) {
            return ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
        }
        if (TextUtils.equals(screenType, SCREEN_PORTRAIT)) {
            return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
        }
        if (TextUtils.equals(screenType, SCREEN_SENSOR)) {
            return ActivityInfo.SCREEN_ORIENTATION_SENSOR;
        }
        return ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
    }


    @Override
    public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
        mResult = null;
        channel = null;
    }

    @Override
    public void onAttachedToActivity(ActivityPluginBinding binding) {
        if (binding == null) {
            return;
        }
        activityBinding = binding;
        activity = activityBinding.getActivity();
        activityBinding.addActivityResultListener(this);
        Log.d("zxx", "获取到activity：" + activity.toString());
    }

    @Override
    public void onDetachedFromActivityForConfigChanges() {

    }

    @Override
    public void onReattachedToActivityForConfigChanges(ActivityPluginBinding binding) {
        if (binding == null) {
            return;
        }

        activityBinding = binding;
        activity = activityBinding.getActivity();
        activityBinding.addActivityResultListener(this);
        Log.d("zxx", "重配置获取到activity：" + activity.toString());
    }

    @Override
    public void onDetachedFromActivity() {
        activity = null;
        activityBinding = null;
        Log.d("zxx", "销毁binding");
    }

    @Override
    public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
        //图片选择
        if (requestCode == MetisseConstant.REQUEST_CODE_MATISSE && resultCode == RESULT_OK) {
            if (data == null || mResult == null) {
                return false;
            }
            List<String> pathList;
            pathList = Matisse.obtainPathResult(data);
            if (pathList == null || pathList.isEmpty()) {
                return false;
            }
            for (String path : pathList) {
                Log.d("zxx", TextUtils.isEmpty(path) ? "" : path);
            }
            mResult.success(pathList);

        }
        //选头像裁剪
        if (requestCode == MetisseConstant.REQUEST_MATISSE_TO_CLIP && resultCode == RESULT_OK) {
            if (data == null || mResult == null) {
                return false;
            }
            List<String> pathList;
            pathList = Matisse.obtainPathResult(data);
            if (pathList == null || pathList.isEmpty()) {
                return false;
            }
            TailorImageActivity.start(activity,
                    pathList.get(0),
                    new File(Environment.getExternalStorageDirectory() + "/matisse_plugin/img_cut", System.currentTimeMillis() +".jpg").getPath(),
                    clipScaleX == 0 ? MetisseConstant.DEFAULT_CLIP_SCALE_X : clipScaleX,
                    clipScaleY == 0 ? MetisseConstant.DEFAULT_CLIP_SCALE_Y : clipScaleY);

        }
        //裁剪返回值
        if (requestCode == MetisseConstant.REQUEST_CODE_CLIP && resultCode == RESULT_OK) {
            if (data == null || mResult == null) {
                return false;
            }
            String path = TailorImageActivity.ClipOptions.createFromBundle(data).getOutputPath();
            mResult.success(path);
            Log.d("zxx", "裁剪后的图片:" + path);
        }
        return false;
    }
}
